package controllers

import (
	"github.com/goravel/framework/contracts/http"
	"github.com/goravel/framework/facades"
	"github.com/goravel/framework/validation"
	httpfacade "github.com/hulutech-web/http_result"
	"goravel/app/http/controllers/common"
	"goravel/app/http/requests"
	"goravel/app/models"
)

type AuthController struct {
	*common.WechatService
}

func NewAuthController() *AuthController {
	return &AuthController{
		//Inject services
	}
}

// AdminLogin manager login.管理员登录
// @Summary 管理员登录
// @Description 登录，管理员通过提交 JSON 格式数据进行登录。
// @Tags AuthController
// @Accept json
// @Produce json
// @Id AuthAdminLogin
// @Param loginData body requests.UserLoginRequest true "登录数据，包含手机号码和密码"
// @Success 200 {object} common.SuccessResponse "登录成功。"
// @Failure 400 {object} common.ErrorResponse "请求参数错误。"
// @Failure 401 {object} common.ErrorResponse "未授权访问。"
// @Failure 500 {object} common.ErrorResponse "内部服务器错误。"
// @OperationID AdminLogin
// @Router   /api/admin/login [post]
func (r *AuthController) AdminLogin(ctx http.Context) http.Response {
	type UserForm struct {
		Username string `form:"username" json:"username"`
		Password string `form:"password" json:"password"`
	}
	var userForm UserForm
	ctx.Request().Bind(&userForm)
	password := userForm.Password
	//验证
	validator, _ := facades.Validation().Make(map[string]any{
		"username": ctx.Request().Input("username", ""),
		"password": ctx.Request().Input("password", ""),
	}, map[string]string{
		"username": "required",
		"password": "required",
	}, validation.Messages(map[string]string{
		"username.required": "名称不能为空",
		"password.required": "密码不能为空",
	}))
	if validator.Fails() {
		return ctx.Response().Json(http.StatusUnprocessableEntity, http.Json{
			"errors": validator.Errors().All(),
		})
	}
	var user models.User
	//手机号密码验证
	facades.Orm().Query().Model(&user).Where("name", userForm.Username).First(&user)

	if user.ID == 0 {
		ctx.Request().AbortWithStatusJson(401, http.Json{
			"message": "error",
			"fail":    "用户不存在,请点击注册",
		})
		return nil
	}
	var user_exist models.User
	facades.Orm().Query().Model(&user_exist).Where("name", userForm.Username).With("Roles").First(&user_exist)
	//解密
	//if user_exist.ID != 1 && len(user.Roles) == 0 {
	//	return ctx.Response().Status(http.StatusInternalServerError).Json(http.Json{
	//		"message": "无权登录",
	//	})
	//}

	if !facades.Hash().Check(password, user_exist.Password) {
		return ctx.Response().Status(http.StatusInternalServerError).Json(http.Json{
			"message": "密码错误",
		})
	} else {
		//	生成token
		token, err1 := facades.Auth(ctx).Login(&user_exist)
		if err1 != nil {
			return ctx.Response().Status(http.StatusInternalServerError).Json(http.Json{
				"message": "token生成失败",
			})
		}

		return ctx.Response().Status(http.StatusOK).Json(http.Json{
			"message": "登录成功",
			"data": struct {
				Token string      `json:"token"`
				User  models.User `json:"user"`
			}{
				Token: token,
				User:  user_exist,
			},
		})
	}
}

// AdminLogout manager login.管理员退出
// @Summary 管理员退出
// @Description 管理员退出。
// @Tags AuthController
// @Accept json
// @Produce json
// @Id AuthAdminLogout
// @Success 200 {object} common.SuccessResponse "退出成功。"
// @Failure 500 {object} common.ErrorResponse "内部服务器错误。"
// @OperationID AdminLogin
// @Router   /api/admin/logout [get]
func (r *AuthController) AdminLogout(ctx http.Context) http.Response {
	err := facades.Auth(ctx).Logout()
	if err != nil {
		return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "退出失败", err.Error())
	}
	return httpfacade.NewResult(ctx).Success("退出成功", nil)
}

func (r *AuthController) Login(ctx http.Context) http.Response {
	var user models.User
	mobile := ctx.Request().Input("mobile", "")
	openid := ctx.Request().Input("openid", "")
	unionid := ctx.Request().Input("unionid", "")
	facades.Log().Info("mobile", mobile)
	facades.Log().Info("openid", openid)
	facades.Log().Info("unionid", unionid)
	if mobile == "" {
		ctx.Request().AbortWithStatusJson(401, http.Json{
			"error": "手机号不能为空",
		})
		return nil
	}
	facades.Orm().Query().Model(&models.User{}).Where("mobile=?", mobile).With("Roles").First(&user)
	if user.ID == 0 {
		ctx.Request().AbortWithStatusJson(500, http.Json{
			"error": "用户不存在,请点击注册",
		})
		return nil
	} else {
		//更新user
		if _, err := facades.Orm().Query().Model(models.User{}).Where("id=?", user.ID).Update(models.User{Openid: openid, Unionid: unionid}); err != nil {
			return ctx.Response().Json(http.StatusInternalServerError, http.Json{
				"error": "更新用户信息失败",
			})
		}
		if token, err2 := facades.Auth(ctx).Login(&user); err2 != nil {
			return ctx.Response().Json(http.StatusInternalServerError, http.Json{
				"error": "用户授权失败",
			})

		} else {
			return ctx.Response().Success().Json(http.Json{
				"data": map[string]interface{}{
					"token": token,
					"user":  user,
				},
				"message": "登录成功",
			})
		}
	}
}

func (r *AuthController) Openid(ctx http.Context) http.Response {

	code := ctx.Request().Input("code")
	openid, unionid, err := r.GetOpenidByCode(code)
	if err != nil {
		ctx.Request().AbortWithStatusJson(500, http.Json{
			"message": "获取openid失败" + err.Error(),
		})
		return nil
	}
	return ctx.Response().Success().Json(http.Json{
		"openid":  openid,
		"unionid": unionid,
	})
}

// Phone 获取手机号
func (r *AuthController) Phone(ctx http.Context) http.Response {
	code := ctx.Request().Input("code")
	phone, err := r.GetPhoneNumberByCode(code)
	if err != nil {
		ctx.Request().AbortWithStatusJson(500, http.Json{
			"msg": "获取手机号失败" + err.Error(),
		})
		return nil
	}
	return ctx.Response().Success().Json(http.Json{
		"phone": phone,
	})
}

// Logout 退出登录
func (r *AuthController) Logout(ctx http.Context) http.Response {
	return nil
}

// 登录
func (r *AuthController) MiniLogin(ctx http.Context) http.Response {
	type UserForm struct {
		Username string `form:"username" json:"username"`
		Password string `form:"password" json:"password"`
	}

	var userForm UserForm
	err := ctx.Request().Bind(&userForm)
	if err != nil {
		return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "参数错误", nil)
	}
	var user models.User
	//get := facades.Cache().Pull(userForm.Mobile)
	//if userForm.Code != get {
	//	return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "验证码错误", nil)
	//}
	//
	//user.Mobile = userForm.Mobile

	facades.Orm().Query().Model(&models.User{}).Where("name = ?", userForm.Username).With("Roles").First(&user)
	if user.ID == 0 {
		return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "用户不存在", nil)
	}
	if token, err2 := facades.Auth(ctx).Login(&user); err2 != nil {
		return ctx.Response().Json(http.StatusInternalServerError, http.Json{
			"error": "用户授权失败",
		})

	} else {
		return ctx.Response().Success().Json(http.Json{
			"data": map[string]interface{}{
				"token": token,
				"user":  user,
			},
			"message": "登录成功",
		})
	}
}

// 注册
func (r *AuthController) MiniLogout(ctx http.Context) http.Response {
	var user models.User
	facades.Auth(ctx).User(&user)
	facades.Auth(ctx).Logout()
	return httpfacade.NewResult(ctx).Success("退出成功", nil)
}

// 修改密码
func (r *AuthController) MiniReset(ctx http.Context) http.Response {
	var resetpasswordRequest requests.ResetPasswordRequest
	errs, err := ctx.Request().ValidateRequest(&resetpasswordRequest)
	if err != nil {
		return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "数据错误", err.Error())
	}
	if errs != nil {
		return httpfacade.NewResult(ctx).ValidError("", errs.All())
	}
	pwd := resetpasswordRequest.Password
	cpwd := resetpasswordRequest.ConfirmPassword
	if pwd != cpwd {
		return httpfacade.NewResult(ctx).ValidError("", map[string]map[string]string{
			"confirm_password": {
				"required": "两次密码不一致",
			},
		})
	}
	var user models.User
	facades.Auth(ctx).User(&user)
	facades.Orm().Query().Model(&models.User{}).Where("id=?", user.ID).First(&user)
	if user.ID == 0 {
		return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "查无该用户", nil)
	}
	password, _ := facades.Hash().Make(pwd)
	if _, err := facades.Orm().Query().Model(models.User{}).Where("id=?", user.ID).Update(models.User{Password: password}); err != nil {
		return httpfacade.NewResult(ctx).Error(http.StatusInternalServerError, "更新用户信息失败", nil)
	}
	return httpfacade.NewResult(ctx).Success("修改成功", nil)
}
